<template>
	<div class="check-history">
		<el-form>
			<el-row :gutter="24">
				<el-col :span="6">
					<el-form-item label="模型版本">
						<el-select
							v-model="form.currentModel"
							placeholder="请选择"
							@change="switchModel"
						>
							<el-option
								v-for="item in modelList"
								:key="item"
								:label="item"
								:value="item"
							/>
						</el-select>
					</el-form-item>
				</el-col>
				<el-col :span="6">
					<el-form-item :label="`置信度(${form.confidence})`">
						<el-slider
							v-model="form.confidence"
							:max="1"
							:min="0.1"
							:step="0.01"
						/>
					</el-form-item>
				</el-col>
			</el-row>
			<el-row :gutter="24">
				<el-col>
					<el-form-item label="显示类型">
						<el-checkbox-group v-model="form.show_category">
							<el-checkbox
								v-for="item in modelInfos"
								:key="item"
								:label="item"
							>
								{{translate(item)}}
							</el-checkbox>
						</el-checkbox-group>
					</el-form-item>
				</el-col>
			</el-row>
		</el-form>

		<el-card class="upload-card">
			<el-upload
				ref="uploadRef"
				class="video-upload"
				action="/api/yolo_model/videoRecognition/"
				:data="uploadFormData"
				:limit="1"
				:multiple="true"
				:disabled="hasPendingTasks"
				drag
				:auto-upload="true"
				:show-file-list="false"
				:on-success="handleUploadSuccess"
				:on-error="handleUploadError"
				:on-progress="handleUploadProgress"
				:on-exceed="handleExceed"
				:before-upload="beforeUpload"
			>
				<el-button
					type="primary"
					:disabled="hasPendingTasks"
				>
					{{ uploadButtonText }}
				</el-button>
				<template #tip>
					<div class="upload-tip">
            <span v-if="isUploading" style="font-size: 30px;">
              视频上传中... ({{ uploadProgress }}%)
            </span>
						<span v-else-if="uploadCompleted" style="font-size: 30px;">
              上传完成，正在识别中...
            </span>
						<span v-else-if="hasPendingTasks" style="font-size: 30px;">
              有{{ pendingCount }}个视频正在处理中，请完成后上传
            </span>
						<span v-else style="font-size: 30px;">
              请上传视频文件
            </span>
					</div>
				</template>
			</el-upload>
		</el-card>

		<el-card class="history-card">
			<div class="result">
				<div class="result-item"
					 :class="[activeName === item.id && 'open']"
					 v-for="(item, index) in historyList"
					 :key="item.id"
					 @click="openResult(item.id)">
					<div class="result-title">
						<el-tag :type="item.status === '已完成' ? 'success' : 'warning'" style="margin-right: 14px">
							{{ item.status }}
						</el-tag>
						<span>视频 {{ index + 1 }}</span>
						<el-icon color="#CDD0D6" class="icon">
							<ArrowRightBold/>
						</el-icon>
					</div>
					<div class="video-wapper" v-if="activeName === item.id">
						<div class="video-item">
							<span>原视频</span>
							<video
								:ref="el => setVideoRef(el, item.id, 'original')"
								:src="`/api${item.video_path}`"
								controls
                autoplay
								style="width: 100%; height: 300px;"
							></video>
						</div>
						<div class="video-item">
							<span>识别结果</span>
							<video
								:ref="el => setVideoRef(el, item.id, 'result')"
								:src="`/api${item.result_path}`"
								controls
                autoplay
								style="width: 100%; height: 300px;"
							></video>
						</div>
					</div>
				</div>
			</div>
		</el-card>
	</div>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { ElMessage, ElNotification, type UploadInstance, type UploadRawFile } from 'element-plus'
import { ArrowRightBold } from '@element-plus/icons-vue'
import { modelVersions, changeModel, yoloModelInfo, videoRecognitionList } from '/@api/yolo_model/hz-system-yolo-model-api'
import {translate} from '/@/utils/translate'
// 状态管理
const uploadCompleted = ref(false)
const isUploading = ref(false)
const uploadProgress = ref(0)

// 表单数据
const form = reactive({
	currentModel: '',
	confidence: 0.5,
	show_category: [] as string[]
})

// 上传相关
const uploadRef = ref<UploadInstance>()

// 历史记录
const historyList = ref<any[]>([])
const activeName = ref<string | null>(null)

// 模型数据
const modelList = ref<string[]>([])
const modelInfos = ref<string[]>([])

// 轮询控制
let pollingTimer: NodeJS.Timeout | null = null

// 计算属性
const pendingCount = computed(() =>
	historyList.value.filter(item => item.status === '识别中').length
)

const hasPendingTasks = computed(() =>
	isUploading.value || pendingCount.value > 0
)

const uploadButtonText = computed(() => {
	if (isUploading.value) return '视频上传中...'
	if (hasPendingTasks.value) return '处理中，请等待...'
	return '上传视频'
})

const uploadFormData = computed(() => ({
	currentModel: form.currentModel,
	confidence: form.confidence,
	show_category: form.show_category.join(',')
}))

// 方法
const setVideoRef = (el: HTMLVideoElement, id: string, type: 'original' | 'result') => {
	if (!videoRefs.value[id]) videoRefs.value[id] = { original: undefined, result: undefined }
	videoRefs.value[id][type] = el
}

const openResult = async (id: string) => {
	activeName.value = activeName.value === id ? null : id
	await nextTick()
}

// 视频同步逻辑
const videoRefs = ref<Record<string, { original?: HTMLVideoElement; result?: HTMLVideoElement }>>({})


// 上传处理
const beforeUpload = () => {
	isUploading.value = true
	uploadCompleted.value = false
	uploadProgress.value = 0
	startPolling(true)
	return true
}

const handleUploadProgress = (event: ProgressEvent) => {
	if (event.lengthComputable) {
		uploadProgress.value = Math.round((event.loaded / event.total) * 100)
	}
	if (uploadProgress.value === 100) {
		uploadCompleted.value = true
	}
}

const handleUploadSuccess = (response: any) => {
	isUploading.value = false
	uploadProgress.value = 100
	uploadCompleted.value = true
	if (response.code === 200) {
		ElMessage.success('视频已加入处理队列')
		loadHistory()
	} else {
		ElMessage.error(response.msg)
		uploadCompleted.value = false
	}
	uploadRef.value?.clearFiles()
}

const handleUploadError = () => {
	isUploading.value = false
	uploadProgress.value = 0
	uploadCompleted.value = false
	ElMessage.error('视频上传失败')
	uploadRef.value?.clearFiles()
	stopPolling()
}

const handleExceed = () => {
	ElMessage.warning('请等待当前视频处理完成后再上传')
}

// 轮询控制
const startPolling = (force = false) => {
	if (!pollingTimer || force) {
		stopPolling()
		pollingTimer = setInterval(async () => {
			try {
				await loadHistory()
				if (!hasPendingTasks.value) {
					stopPolling()
					uploadCompleted.value = false
					ElNotification.success('所有视频处理完成')
				}
			} catch (error) {
				stopPolling()
			}
		}, 3000)
	}
}

const stopPolling = () => {
	if (pollingTimer) {
		clearInterval(pollingTimer)
		pollingTimer = null
	}
}

// 初始化
const loadHistory = async () => {
	try {
		const res = await videoRecognitionList({})
		historyList.value = res.data.records
	} catch (error) {
		ElMessage.error('获取识别历史失败')
	}
}

const initData = async () => {
	try {
		const modelRes = await modelVersions()
		modelList.value = modelRes.data.model_version
		form.currentModel = modelList.value[0]

		const infoRes = await yoloModelInfo()
		modelInfos.value = Object.values(infoRes.data.supported_classes)
		form.show_category = [...modelInfos.value]

		await loadHistory()
	} catch (error) {
		ElMessage.error('初始化数据失败')
	}
}

const switchModel = async (model: string) => {
	try {
		const res = await changeModel(model)
		ElMessage({ type: res.code === 200 ? 'success' : 'error', message: res.msg })
	} catch (error) {
		ElMessage.error('模型切换失败')
	}
}

// 生命周期
onMounted(() => {
	initData()
	startPolling()
})

onBeforeUnmount(() => {
	stopPolling()
})
</script>

<style lang="scss" scoped>
.check-history {
	padding: 14px;

	.confidence-container {
		display: flex;
		align-items: center;
		gap: 12px;

		.confidence-value {
			min-width: 40px;
			text-align: right;
		}
	}

	.upload-card {
		margin-top: 20px;

		.upload-tip {
			color: #666;
			font-size: 12px;
			margin-top: 8px;
		}
	}

	.history-card {
		margin-top: 20px;
	}
}

.result {
	display: flex;
	flex-direction: column;
}

.result-item {
	height: 60px;
	overflow: hidden;
	transition: height 0.3s;

	.result-title {
		padding: 10px 0;
		border-bottom: 1px solid #CDD0D6;
		display: flex;
		align-items: center;
		position: relative;

		.icon {
			position: absolute;
			right: 14px;
		}
	}

	.video-wapper {
		width: 100%;
		height: fit-content;
		display: flex;
		align-items: center;
		justify-content: space-between;

		.video-item {
			width: 49%;
			display: flex;
			align-items: center;
			flex-direction: column;
		}
	}
}

.open {
	height: fit-content;
}

:deep(.el-upload__dragger.is-disabled) {
	cursor: not-allowed;
	border-color: #ddd;
	background-color: #f5f7fa;

	&:hover {
		border-color: #ddd;
	}
}

.video-upload {
	.el-upload-dragger {
		position: relative;
		overflow: hidden;

		&::after {
			content: '';
			position: absolute;
			bottom: 0;
			left: 0;
			height: 4px;
			background: var(--el-color-primary);
			width: v-bind('uploadProgress + "%"');
			transition: width 0.3s ease;
		}
	}

	.el-upload-dragger.is-disabled::after {
		display: none;
	}
}
</style>
